package com.xbongbong.pro.statistic.help;

import com.alibaba.fastjson.JSONObject;
import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.paas.constant.TimeConstant;
import com.xbongbong.paas.elasticsearch.util.EsHelper;
import com.xbongbong.paas.enums.IndexTypeEnum;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.paas.toolbox.util.DateUtil;
import com.xbongbong.paas.toolbox.util.JsonHelperUtil;
import com.xbongbong.pro.constant.RemindConstant;
import com.xbongbong.pro.detailtab.dto.RemindDTO;
import com.xbongbong.pro.enums.errorcodes.CustomerErrorCodeEnum;
import com.xbongbong.pro.message.model.PushModel;
import com.xbongbong.pro.service.toolbox.statistic.help.ChartDtoHelp;
import com.xbongbong.pro.service.toolbox.statistic.help.ChartQueryHelp;
import com.xbongbong.pro.statistic.result.pojo.ElasticAggsPojo;
import com.xbongbong.pro.statistic.result.pojo.PanoramaPojo;
import com.xbongbong.pro.statistic.result.pojo.dto.PanoramaDTO;
import com.xbongbong.saas.domain.entity.TagLinkEntity;
import com.xbongbong.saas.domain.entity.ext.CustomerEntityExt;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.CustomerManagementEnum;
import com.xbongbong.saas.model.CustomerModel;
import com.xbongbong.saas.model.TagLinkModel;
import com.xbongbong.sys.domain.entity.UserEntity;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * 提示帮助类
 *
 * @author 徐俊杰
 * @version v1.0
 * @date 2019/6/3 10:22
 * @since v1.0
 */
@Component
public class RemindHelp {
    private static final Logger LOG = LoggerFactory.getLogger(RemindHelp.class);
    @Resource
    private CustomerModel customerModel;
    @Resource
    private ChartDtoHelp chartDtoHelp;
    @Resource
    private ChartQueryHelp chartQueryHelp;
    @Resource
    private EsHelper esHelper;
    @Resource
    private PushModel pushModel;
    @Resource
    private TagLinkModel tagLinkModel;

    /**
     * 客户跟进相关
     *
     * @param remindDTO 入参
     * @return java.lang.String
     * @throws XbbException 空值异常
     * @author 徐俊杰
     * @date 2019/6/3 19:22
     * @since v1.0
     */
    public String customerRemind2Customer(RemindDTO remindDTO) throws XbbException {
        //获取客户信息
        CustomerEntityExt customerEntityExt = customerModel.getByKey(remindDTO.getDataId(), remindDTO.getCorpid());
        if (customerEntityExt == null) {
            throw new XbbException(CustomerErrorCodeEnum.API_ERROR_201001, CustomerErrorCodeEnum.API_ERROR_201001.getMsg());
        }
        JSONObject data = JsonHelperUtil.getJSONObject(customerEntityExt.getData());
        Long lastConnectTime = data.getLongValue(CustomerManagementEnum.LAST_CONNECT_TIME.getAttr());
        long addTime = customerEntityExt.getAddTime();
        int now = DateUtil.getInt();
        //未联系且n天内创建的客户需提示跟进（最近联系时间为0，现在的时间-创建时间<=三十天）
        int dayAdd = DateTimeUtil.lastConnect(addTime, now);
        boolean addTimeNotOver = Objects.equals(lastConnectTime, 0L) && dayAdd <= RemindConstant.REMIND_DAY_LIMIT;
        boolean addTimeOver = Objects.equals(lastConnectTime, 0L) && dayAdd > RemindConstant.REMIND_DAY_LIMIT;
        String remind = "";
        if (addTimeNotOver) {
            //新建客户30天内未跟进
            remind = I18nMessageUtil.getMessage(RemindConstant.NOT_CONNECT_NEW_CUSTOMER);
        } else if (addTimeOver) {
            //新建客户超过30天未跟进
            remind = I18nMessageUtil.getMessage(RemindConstant.NOT_CONNECT_CUSTOMER);
        } else {
            //客户超过n天未跟进逻辑
            int dayDifference = DateTimeUtil.lastConnect(lastConnectTime, now);
            if (dayDifference >= RemindConstant.REMIND_DAY_LIMIT) {
                remind = String.format(I18nMessageUtil.getMessage(RemindConstant.NOT_CONNECT), dayDifference);
            }
        }
        return remind;
    }

    /**
     * 有N个机会将于30天内到期
     *
     * @param remindDTO 入参
     * @return java.lang.String
     * @throws XbbException 异常
     * @author 徐俊杰
     * @date 2019/6/4 15:45
     * @since v1.0
     */
    public String customerRemind2Opportunity(RemindDTO remindDTO) throws XbbException {
        //员工权限
        PanoramaPojo panoramaPojo = transformRemind2Panorama(remindDTO);
        //封装查询参数
        BoolQueryBuilder opportunityQuery = chartQueryHelp.remindQuery4Opportunity(panoramaPojo);
        //查询
        ElasticAggsPojo elasticAggsPojo = esHelper.elasticAggs(IndexTypeEnum.IDX_SAAS_OPPORTUNITY, opportunityQuery, null);
        String count = elasticAggsPojo.getTotal();
        return dealWithZero(count, String.format(I18nMessageUtil.getMessage(RemindConstant.OPPORTUNITY_EXPIRE), "%s", RemindConstant.REMIND_DAY_LIMIT));
    }

    /**
     * 最近7天有N条该客户访客计划未处理
     *
     * @param remindDTO 入参
     * @return java.lang.String
     * @throws XbbException copy时异常
     * @author 徐俊杰
     * @date 2019/6/6 9:23
     * @since v1.0
     */
    public String customerRemind2CommunicatePlan(RemindDTO remindDTO) throws XbbException {
        PanoramaPojo panoramaPojo = transformRemind2Panorama(remindDTO);
        //封装查询参数
        BoolQueryBuilder communicatePlanQuery = chartQueryHelp.remindQuery4CommunicatePlan(panoramaPojo);
        ElasticAggsPojo elasticAggsPojo = esHelper.elasticAggs(IndexTypeEnum.IDX_SAAS_COMMUNICATE_PLAN, communicatePlanQuery, null);
        String count = elasticAggsPojo.getTotal();
        return dealWithZero(count, String.format(I18nMessageUtil.getMessage(RemindConstant.COMMUNICATE_PLAN_UNTREATED), RemindConstant.REMIND_DAY_LATELY, "%s"));
    }

    /**
     * 最近7天客户跟进提醒条数
     *
     * @param remindDTO 入参
     * @return java.lang.String
     * @author 徐俊杰
     * @date 2019/6/10 9:45
     * @since v1.0
     */
    public String customerRemind2Push(RemindDTO remindDTO) {
        Integer endTime = DateUtil.getInt();
        Integer startTime = endTime - TimeConstant.SECONDS_PER_WEEK;
        Long dataId = remindDTO.getDataId();
        String corpid = remindDTO.getCorpid();
        Integer businessType = remindDTO.getBusinessType();
        Integer pushCount = pushModel.getPushCount(dataId, corpid, businessType, startTime, endTime);
        String count = String.valueOf(pushCount);
        return dealWithZero(count, String.format(I18nMessageUtil.getMessage(RemindConstant.CUSTOMER_COMMUNICATE_REMIND), RemindConstant.REMIND_DAY_LATELY, "%s"));
    }

    /**
     * %s由于【%s】即将在%s天内退回公海池
     *
     * @param remindDTO 入参
     * @return java.lang.String
     * @author 徐俊杰
     * @date 2019/6/10 10:33
     * @since v1.0
     */
    public String customerRemind2ReturnToPublic(RemindDTO remindDTO) {
        String corpid = remindDTO.getCorpid();
        Long dataId = remindDTO.getDataId();
        List<Long> dataIdList = Collections.singletonList(dataId);
        Map<Long, TagLinkEntity> tagLinkEntityMap = tagLinkModel.getPublicTagLink(corpid, dataIdList, XbbRefTypeEnum.CUSTOMER_PUBLIC.getCode());
        TagLinkEntity tagLinkEntity = tagLinkEntityMap.get(dataId);
        if (tagLinkEntity == null) {
            return "";
        } else {
            //StringConstant内PUBLIC_TAG_MEMO
            return tagLinkEntity.getMemo();
        }
    }

    /**
     * 有N个合同将于30天内到期
     *
     * @param remindDTO 入参
     * @return java.lang.String
     * @throws XbbException 异常
     * @author 徐俊杰
     * @date 2019/6/10 11:23
     * @since v1.0
     */
    public String customerRemind2Contract(RemindDTO remindDTO) throws XbbException {
        //员工权限
        PanoramaPojo panoramaPojo = transformRemind2Panorama(remindDTO);
        //封装查询参数
        BoolQueryBuilder contractQuery = chartQueryHelp.remindQuery4Contract(panoramaPojo);
        //查询
        ElasticAggsPojo elasticAggsPojo = esHelper.elasticAggs(IndexTypeEnum.IDX_SAAS_CONTRACT, contractQuery, null);
        String count = elasticAggsPojo.getTotal();
        return dealWithZero(count, String.format(I18nMessageUtil.getMessage(RemindConstant.CONTRACT_EXPIRE), "%s", RemindConstant.REMIND_DAY_LIMIT));
    }

    /**
     * 有N笔回款将于30天内收款
     *
     * @param remindDTO 入参
     * @return java.lang.String
     * @throws XbbException 异常
     * @author 徐俊杰
     * @date 2019/6/10 14:30
     * @since v1.0
     */
    public String customerRemind2Payment(RemindDTO remindDTO) throws XbbException {
        //员工权限
        PanoramaPojo panoramaPojo = transformRemind2Panorama(remindDTO);
        BoolQueryBuilder paymentQuery = chartQueryHelp.remindQuery4Payment(panoramaPojo);
        //查询
        ElasticAggsPojo elasticAggsPojo = esHelper.elasticAggs(IndexTypeEnum.IDX_SAAS_PAYMENT, paymentQuery, null);
        String count = elasticAggsPojo.getTotal();
        return dealWithZero(count, String.format(I18nMessageUtil.getMessage(RemindConstant.PAYMENT_REMIND), "%s", RemindConstant.REMIND_DAY_LIMIT));
    }

    /**
     * 有N个报价单将于30天内到期
     *
     * @param remindDTO 入参
     * @return java.lang.String
     * @throws XbbException elasticAggs会出现异常
     * @author 徐俊杰
     * @date 2019/8/26 17:11
     * @since v1.0
     */
    public String customerRemind2Quotation(RemindDTO remindDTO) throws XbbException {
        PanoramaPojo panoramaPojo = transformRemind2Panorama(remindDTO);
        //封装查询参数
        BoolQueryBuilder quotationQuery = chartQueryHelp.remindQuery4Quotation(panoramaPojo);
        //查询
        ElasticAggsPojo elasticAggsPojo = esHelper.elasticAggs(IndexTypeEnum.IDX_SAAS_QUOTATION, quotationQuery, null);
        String count = elasticAggsPojo.getTotal();
        return dealWithZero(count, String.format(I18nMessageUtil.getMessage(RemindConstant.QUOTATION_EXPIRE), "%s", RemindConstant.REMIND_DAY_LIMIT));
    }

    /**
     * 将提示DTO转换成全景图Pojo
     *
     * @param remindDTO 提示标准入参
     * @return com.xbongbong.pro.statistic.result.pojo.PanoramaPojo
     * @throws XbbException copy时抛出异常
     * @author 徐俊杰
     * @date 2019/6/5 9:25
     * @since v1.0
     */
    private PanoramaPojo transformRemind2Panorama(RemindDTO remindDTO) throws XbbException {
        UserEntity userEntity = BeanUtil.copyProperties(remindDTO.getLoginUser(), UserEntity.class, false);
        PanoramaDTO panoramaDTO = BeanUtil.copyProperties(remindDTO, PanoramaDTO.class, false);
        return chartDtoHelp.getPanoramaPojo(userEntity, panoramaDTO);
    }

    /**
     * 处理返回值为0的情况
     *
     * @param count ES聚合结果
     * @param rawRemind       未经处理的提示
     * @return java.lang.String
     * @author 徐俊杰
     * @date 2019/6/6 10:32
     * @since v1.0
     */
    private String dealWithZero(String count, String rawRemind) {
        if (Objects.equals(count, RemindConstant.ZERO)) {
            return "";
        } else {
            return String.format(rawRemind, count);
        }
    }
}
